package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.UserTypeEnum;
import cn.huiyunche.base.service.framework.utils.TmsQueueApi;
import cn.huiyunche.base.service.interfaces.DUserAddressService;
import cn.huiyunche.base.service.interfaces.UserService;
import cn.huiyunche.base.service.mappers.BAreaMapper;
import cn.huiyunche.base.service.mappers.DUserAddressMapper;
import cn.huiyunche.base.service.mappers.DWaybillMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.vo.*;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.alibaba.fastjson.JSONArray;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DUserAddressServiceImpl implements DUserAddressService {

	private static final Logger LOGGER = LoggerFactory.getLogger(DUserAddressServiceImpl.class);

	@Autowired
	private UserService userService = null;

	@Autowired
	private DUserAddressMapper dUserAddressMapper = null;

	@Autowired
	private BAreaMapper bAreaMapper = null;

	@Autowired
    private DWaybillMapper dWaybillMapper;

    private BAreaMapper getBAreaMapper() {
		return this.bAreaMapper;
	}

	private UserService getUserService() {
		return this.userService;
	}

	private DUserAddressMapper getDUserAddressMapper() {
		return this.dUserAddressMapper;
	}

	@Override
	public List<DUserAddress> getList(String phone) {
		LOGGER.info("select user address params phone : {}.", phone);
		List<DUserAddress> list = new ArrayList<>();
		try {
			SUser user = this.getUser(phone);
			if (null != user) {
				DUserAddressExample example = new DUserAddressExample();
				example.createCriteria().andUserIdEqualTo(user.getId());
				return this.getDUserAddressMapper().selectByExample(example);
			}
		} catch (Exception e) {
			LOGGER.error("select user address params phone : {}, error : {}.", phone, e);
			throw new BusinessException("根据用户电话查询常用地址异常");
		}
		return list;
	}

	@Override
	public SUser getUser(String phone) {
		LOGGER.info("select user by phone params phone : {}.", phone);
		try {
			SUserExample userSearch = new SUserExample();
			userSearch.createCriteria().andUserTypeEqualTo(UserTypeEnum.SEND_DRIVER.getValue()).andPhoneEqualTo(phone);
			List<SUser> userList = this.getUserService().selectByExample(userSearch);
			if (CollectionUtils.isNotEmpty(userList)) {
				return userList.get(0);
			}
		} catch (Exception e) {
			LOGGER.error("select user by phone params phone : {}, error : {}.", phone, e);
			throw new BusinessException("更具用户电话查询用户异常");
		}
		return null;
	}

	@Override
	public List<TmsBareaVo> getList() throws Exception {
		return this.getBarea(null);
	}

	private List<TmsBareaVo> getBarea(String phone) throws Exception {
		SUser user = new SUser();
		List<DUserAddressShowVo> list = new ArrayList<DUserAddressShowVo>();
		List<BArea> areas = this.selectProvinceList();
		List<TmsBareaVo> bareaVos = new ArrayList<>();

		if (StringUtils.isBlank(phone)) {
			UserShowVo usv = this.getUserService().getCurrentUser();
			if (null != usv) {
				user = this.getUserService().getById(usv.getId());
			}
		} else {
			user = this.getUserService().getByPhone(phone, UserTypeEnum.SEND_DRIVER.getValue());
		}

		LOGGER.info("select user address current user: {}.", user.toString());

		if (null != user) {
			DUserAddressExample example = new DUserAddressExample();
			example.createCriteria().andUserIdEqualTo(user.getId());
			List<DUserAddress> duaLists = this.getDUserAddressMapper().selectByExample(example);
			if (CollectionUtils.isNotEmpty(duaLists)) {
				for (DUserAddress dUserAddress : duaLists) {
					DUserAddressShowVo vo = new DUserAddressShowVo();
					BeanUtils.copyProperties(dUserAddress, vo);
					list.add(vo);
				}
			}
			List<String> codeList = list.stream().map(value -> value.getReceiptProvinceCode())
					.collect(Collectors.toList());
			areas.stream().forEach(value -> {
				TmsBareaVo vo = new TmsBareaVo();
				try {
					PropertyUtils.copyProperties(vo, value);
					vo.setIsCheck(false);
					bareaVos.add(vo);
				} catch (Exception e) {
					LOGGER.error("copyVo error: {}", e);
					throw new BusinessException("查询意向线路异常");
				}
			});
			bareaVos.stream().filter(value -> codeList.contains(value.getCode()))
					.forEach(value -> value.setIsCheck(true));
		}

		return bareaVos;
	}

	public List<BArea> selectProvinceList() throws BusinessException {
		BAreaExample search = new BAreaExample();
		BAreaExample.Criteria areaSearch = search.createCriteria();
		areaSearch.andLevelEqualTo("1");
		areaSearch.andIsSendbydriverEqualTo(true);
		areaSearch.andIsTransportEqualTo(true);
		return this.getBAreaMapper().selectByExample(search);
	}

	@Override
	public Long modify(String addressVo) throws Exception {
		UserShowVo user = this.getUserService().getCurrentUser();
		if (null == user) {
			LOGGER.info("current user is null");
			throw new BusinessException("当前用户不存在");
		}
		LOGGER.info("modify user address params: {}, current user: {}", addressVo, user.toString());
		
		try{
			List<TmsBareaVo> bareaVos = new ArrayList<>();
			if (StringUtils.isNotEmpty(addressVo)) {
				bareaVos = JSONArray.parseArray(addressVo, TmsBareaVo.class);
			}
			// 删除意向线路
			DUserAddressExample example = new DUserAddressExample();
			example.createCriteria().andUserIdEqualTo(user.getId());
			this.getDUserAddressMapper().deleteByExample(example);
			if (CollectionUtils.isNotEmpty(bareaVos)) {
				// 删除意向路线队列中缓存手机号
				// 2016-12-23 15:16:20 hdy[Tuffy]
				TmsQueueApi.removeDriverIntentionaLines4User(user.getPhone());
				bareaVos.stream().forEach(value -> {
					DUserAddress dua = new DUserAddress();
					dua.setUserId(user.getId());
					dua.setDepartProvinceCode("360000");
					dua.setDepartProvinceName("江西省");
					dua.setReceiptProvinceCode(value.getCode());
					dua.setReceiptProvinceName(value.getName());
					this.getDUserAddressMapper().insertSelective(dua);
				});
			}
			LOGGER.info("modify user address params: {}, result: {}", addressVo, bareaVos);
		}catch (Exception e){
			LOGGER.error("modify user address error:{}", e);
			throw new  BusinessException("修改意向方向异常.");
		}
		return 0L;
	}
	
	/**
	 * 获取队列司机意向方向
	 * 
	 * @param phone
	 * @return
	 */
	private List<DUserAddress> getDriverList(String phone) {
		List<TmsQueueDriverVo> driverVos = TmsQueueApi.purposeList();
		LOGGER.info("current driver phone : {}", phone);
		List<DUserAddress> duaLists = new ArrayList<>();
		driverVos.stream().filter(value -> value.getPhone().equals(phone)).collect(Collectors.toList()).forEach(val -> {
			List<TmsQueueDriverLineVo> lineVos = val.getLines();
			LOGGER.info("getBarea current driver lines : {}", lineVos);
			lineVos.stream().forEach(v -> {
				DUserAddress dAddress = new DUserAddress();
				dAddress.setReceiptProvinceName(v.getTo());
				duaLists.add(dAddress);
				LOGGER.info("duaLists info : {}", duaLists);
			});
		});
		return duaLists;
	}

	@Override
	public int del(Long id) throws BusinessException {
		LOGGER.info("delete user address params id: {}", id);
		if (id == null) {
			LOGGER.error("DUserAddressServiceImpl.del param id must not be null");
			throw new BusinessException("意愿路线ID不能为空");
		}
		return this.getDUserAddressMapper().deleteByPrimaryKey(id);
	}

    @Override
    public List<DUserAddress> geUserCheckedList(Long sUserId) throws Exception {
		LOGGER.info("DUserAddressServiceImpl.geUserCheckedList param : {}", sUserId);

		if ( null == sUserId ) {
			LOGGER.error("DUserAddressServiceImpl.geUserCheckedList param sUserId must not be null");
			throw new IllegalArgumentException("用户主键不能为空");
		}

		DUserAddressExample example = new DUserAddressExample();
		example.createCriteria().andUserIdEqualTo(sUserId);

		return dUserAddressMapper.selectByExample(example);
    }

    @Override
	public List<TmsBareaVo> getListByPhone(String phone) throws Exception {
		return this.getBarea(phone);
	}
}
